package com.example.myapplication.ui;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.graphics.Bitmap;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.myapplication.R;
import com.example.myapplication.tools.ZKNIDFPSensor.FingerprintSensor;
import com.example.myapplication.tools.ZKNIDFPSensor.ZKNIDFPSensorListener;
import com.example.myapplication.tools.ZKUSBManager.ZKUSBManager;
import com.example.myapplication.tools.ZKUSBManager.ZKUSBManagerListener;
import com.zkteco.android.biometric.core.utils.LogHelper;
import com.zkteco.android.biometric.core.utils.ToolUtils;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class FingerActivity extends AppCompatActivity {

    private static final int ZKTECO_VID =   0x1b55;
    private static final String TAG = "===========>>";
    private final int REQUEST_PERMISSION_CODE = 9;
    private ZKUSBManager zkusbManager = null;
    private TextView textView = null;
    private ImageView imageView = null;
    private EditText editText = null;
    private FingerprintSensor fingerprintSensor = new FingerprintSensor();
    private int usb_vid = ZKTECO_VID;
    private int usb_pid = 0;
    private boolean bStarted = false;
    private int deviceIndex = 0;
    private boolean isReseted = false;
    private byte[]  idTemplate1 = null;
    private byte[]  idTemplate2 = null;

    private byte[] ttempByte = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_finger);
        initUI();
        zkusbManager = new ZKUSBManager(this.getApplicationContext(), zkusbManagerListener);
        zkusbManager.registerUSBPermissionReceiver();
    }

    private ZKUSBManagerListener zkusbManagerListener = new ZKUSBManagerListener() {
        @Override
        public void onCheckPermission(int result) {
            afterGetUsbPermission();
        }

        @Override
        public void onUSBArrived(UsbDevice device) {
            if (bStarted)
            {
                closeDevice();
                tryGetUSBPermission();
            }
        }

        @Override
        public void onUSBRemoved(UsbDevice device) {
            LogHelper.e("usb removed!");
        }
    };


    private void initUI() {
        textView = (TextView)findViewById(R.id.txtResult);
        imageView = (ImageView)findViewById(R.id.imageFP);
        editText = (EditText)findViewById(R.id.editFeatureFileName);
        editText.setText("tg.txt");
    }

    //获取指纹信息，对比指纹
    private ZKNIDFPSensorListener zknidfpSensorListener = new ZKNIDFPSensorListener() {
        @Override
        public void onCapture(byte[] fpImage) {
            final Bitmap bitmap = ToolUtils.renderCroppedGreyScaleBitmap(fpImage, fingerprintSensor.getImageWidth(), fingerprintSensor.getImageHeight());
            runOnUiThread(new Runnable() {
                public void run() {
                    imageView.setImageBitmap(bitmap);
                }
            });
            byte imageQuality = fingerprintSensor.getImageQuality(fpImage);
            String strText;
            strText = "image quality:" + imageQuality;
            if(imageQuality > 60){
                ttempByte = new byte[fpImage.length];
                System.arraycopy(fpImage,0,ttempByte,0,fpImage.length);
            }
            if (imageQuality < 45 || null == idTemplate1) {
                setResult(strText);
                return;
            }
            float score = fingerprintSensor.imageMatch(fpImage, idTemplate1);
            if (score < 0.35 && null != idTemplate2)    //第一个比对失败比对第二个
            {
                score = fingerprintSensor.imageMatch(fpImage, idTemplate2);
            }
            strText += "\r\n";
            strText += "Match result:" + score;
            setResult(strText);
        }

        @Override
        public void onException(int count) {
            LogHelper.e("usb exception!!!");
            if (!isReseted) {
                fingerprintSensor.resetEx(deviceIndex, getApplicationContext(), usb_vid, usb_pid);
                isReseted = true;
            }
        }
    };

    private boolean enumSensor()
    {
        UsbManager usbManager = (UsbManager)this.getSystemService(Context.USB_SERVICE);
        for (UsbDevice device : usbManager.getDeviceList().values()) {
            int device_vid = device.getVendorId();
            int device_pid = device.getProductId();
            if (device_vid == ZKTECO_VID && (device_pid >= 0x0300 && device_pid <= 0x0310))
            //if (device_vid == ZKTECO_VID && device_pid == 0x0304) //FS200-R
            {
                usb_pid = device_pid;
                return true;
            }
        }
        return false;
    }


    private void tryGetUSBPermission() {
        zkusbManager.initUSBPermission(usb_vid, usb_pid);
    }

    private void afterGetUsbPermission()
    {
        openDevice();
    }

    private void openDevice()
    {
        isReseted = false;
        boolean bResult = fingerprintSensor.open(deviceIndex, getApplicationContext(), usb_vid, usb_pid);
        if (bResult)
        {
            {
                // device parameter
                LogHelper.e("sdk version" + fingerprintSensor.getSDKVersion());
                LogHelper.e("firmware version" + fingerprintSensor.getFirmwareVersion());
                LogHelper.e("serial:" + fingerprintSensor.getSerialNumber());
                LogHelper.e("width=" + fingerprintSensor.getImageWidth() + ", height=" + fingerprintSensor.getImageHeight());
            }
            fingerprintSensor.setDeviceListener(zknidfpSensorListener);
            fingerprintSensor.startCapture();
            bStarted = true;
            textView.setText("connect success!");
        }
        else
        {
            fingerprintSensor.resetEx(deviceIndex, getApplicationContext(), usb_vid, usb_pid);
            textView.setText("connect failed!");
        }
    }

    private void closeDevice()
    {
        if (bStarted)
        {
            fingerprintSensor.stopCapture();
            fingerprintSensor.close();
            bStarted = false;
        }
    }

    public void onBnStart(View view)
    {
        if (bStarted)
        {
            textView.setText("Device already connected!");
            return;
        }
        if (!enumSensor())
        {
            textView.setText("Device not found!");
            return;
        }
        tryGetUSBPermission();
    }

    public void onBnStop(View view)
    {
        if (!bStarted)
        {
            textView.setText("Device not connected!");
            return;
        }
        closeDevice();
        textView.setText("Device closed!");
    }

    public static byte[] readFile(final String filePath) {
        DataInputStream dis = null;
        ByteArrayOutputStream baos = null;

        try {
            dis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
            byte[] buffer = new byte[4096];
            int len = 0;
            int count = 0;
            baos = new ByteArrayOutputStream();

            while ((count = dis.read(buffer, 0, buffer.length)) > 0) {
                len += count;
                baos.write(buffer, 0, count);
            }
            if (len > 0) {
                return baos.toByteArray();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (dis != null) {
                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return null;
    }

    private void setResult(String result)
    {
        final String mStrText = result;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                textView.setText(mStrText);
            }
        });
    }

    //导入信息
    public void onBnImport(View view) {
//        if (!bStarted) {
//            textView.setText("Device not connected!");
//            return;
//        }
//        String strFileName = editText.getText().toString();
//        if (null == strFileName || strFileName.isEmpty()) {
//            textView.setText("Please input filepath!");
//            return;
//        }
//        String temp = Environment.getExternalStorageDirectory().getPath() + "/" + strFileName;
//        File f = new File(temp);
//        f.exists();
//        byte[] tempData = readFile(temp);
////        if (null == tempData || (tempData.length != 512 && tempData.length != 1024)) {
//        if (null == tempData || (tempData.length < 512)) {
//            textView.setText("invalid template data!");
//            return;
//        }
//        idTemplate1 = new byte[512];
//        idTemplate2 = null;
//        System.arraycopy(tempData, 0, idTemplate1, 0, 512);
////        if (tempData.length == 1024) {
//        if (tempData.length >= 1024) {
//            idTemplate2 = new byte[512];
//            System.arraycopy(tempData, 512, idTemplate2, 0, 512);
//        }
        idTemplate1 = ttempByte;
        Log.e(TAG, "onBnImport: " + idTemplate1.length);

//        byte[] tempData = "S/dTUzIxAAACtLkECAUHCc7QAAACtWkBAABiglkVebTNAD9ktAAcADrryQDtADtkJADJtDFU8gCkAORIybQVAcA7bwD4AAHQggDcAD1koACktF5khwADAVdkc7QRARNkYwDSASLkqwAqAVg6tQAktHtkdwChAMJksbT3AEdkSAAFAEXQpwAXAVtfHABttBtkZQBDALNkSbQrAPpkcQU7O+xXaP+J8z8IcPbns4d+qvciEwL4sEcOC8frPmWjenwy6Y9BihIKNAGAGkIEGVmGGosjWzcHOapW3fScg3UNTAxOkmPHJP0QLs7JSXpWBEeB8x23y+PCKQ44E4hZH+pHCSNCmAX0ob/Jl/un7xIX9sPb/Kp9poVHgZhO/v8fICYBxJcWDAwAMxLt/v3Aw0hLwA4AMR8o/znzRE4PANs2SVhpypHBAwBuJEXCC7R3JwP//8CdwAG0cSp3wAQAgC5yMAoAcjwAODpoW7MBY0F9iHzJAGn2B17AwUQ9wgBh83BnahEA6JeTcnRTw8L+fILVANfYl8HBZ2zBBHDCtwHdbhP+BMXacapdFAAfheI6RDH/PzjAwAoAv54CSSs+/xMA7VqidsiFwcGLdQfFeqayIv3AAwBjY23GogEiot7A/zs9/Ev+///9wP+DwE6/AWWrYJ2XBY0XtCes3sBB//Y7wkr+RlkEAEQGTJ68AUrDRoTCBcEQtN/Gp2eEwUmJgbAB4M40WwTFec3ykgUAhs4pOB0FtLbZMDE8F8Uvzn3//v7//cA6/MJJ/v////3BOv/9dP4XADPdzAT+/0ou/DH+/zWBMAG0ze80/QMAA/A/dAUAtvhAMMkAdU6q/f78+vc+/PxI/BEQhAiGP/3+S//8/fn6/jj+/p8XEG0LpCo7//6o+v4p/P7AOFRQ9gELQwEAAM5FULQ=".getBytes(StandardCharsets.UTF_8);
//        idTemplate1 = new byte[512];
//        idTemplate2 = null;
//        System.arraycopy(tempData, 0, idTemplate1, 0, 512);
//        if (tempData.length == 1024) {
//            idTemplate2 = new byte[512];
//            System.arraycopy(tempData, 512, idTemplate2, 0, 512);
//        }
//        textView.setText("Import success!");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (bStarted)
        {
            closeDevice();
        }
        zkusbManager.unRegisterUSBPermissionReceiver();
    }
}